/* 
    // Page 处理下拉刷新与触底加载
    // 王欢
    // 2020/5/21
    // ## 注意
    //    默认开启下拉刷新 但是要在 json配置开启  enablePullDownRefresh:true
    // ## 示例 1 使用
    // m-tabs为依赖uview组件库tabs组件 兼容多端  二次封装的tabs自定义组件
    <m-tabs
        :list="v_tabsInfo"
        :current="v_tabsIndex"
        name="title"
        @change="v_tabsChange"
    >

        <view class="m-tabs-wrapper-nav">
            <!-- 列表视图   -->
            <view class="item" 
                v-for="(item,index) in v_tabsInfo[v_tabsIndex].list "
                :key="index"
            >item view</view>
            <!-- 提示   -->
            <block>
                <view v-if="v_tabsInfo[v_tabsIndex].end ">
                    <u-empty description="当前列表没有内容哦" v-if=" !v_tabsInfo[v_tabsIndex].list.length " />
                    <u-divider v-else-if="v_tabsEndNoticShow && v_tabsInfo[v_tabsIndex].count !== 1 ">
                        {{ v_tabsEndNoticText }}
                    </u-divider>
                </view>
                <u-loading size="24px" v-if=" v_tabsReachBottomLoading " class="">
                    {{ v_tabsReachBottomLoadingText }}
                </u-loading>
            </block>
        </view>
    </m-tabs>
    // ## 示例 2  
    // 使用 vant h5
    ### vant tabs demo
    <van-tabs
      :sticky="true"
      :swipeable="true"
      :animated="true"
      v-model="v_tabsIndex"
      @change="v_tabsChange"
      class="__van-tabsCover"
    >
      <van-tab
        v-for="(item, index) in v_tabsInfo"
        :key="index"
        :title="item.title"
        :data-index="index"
      >
        <!-- 列表视图   -->
        <view
          class="item"
          v-for="(listItem, listIndex) in v_tabsInfo[v_tabsIndex].list"
          :key="listIndex"
          >{{ listIndex }}-item view</view
        >
         <!-- 提示   -->
        <block>
            <view v-if="v_tabsInfo[v_tabsIndex].end ">
                <van-empty description="暂无订单信息" v-if=" !v_tabsInfo[v_tabsIndex].list.length " />
                <van-divider v-else-if="v_tabsEndNoticShow && v_tabsInfo[v_tabsIndex].count !== 1 ">
                    {{ v_tabsEndNoticText }}
                </van-divider>
            </view>
            <van-loading size="24px" v-if=" v_tabsReachBottomLoading " class="__van-tabsLoading">
                {{ v_tabsReachBottomLoadingText }}
            </van-loading>
        </block> 
      </van-tab>
    </van-tabs>
    
*/
/* 2021/8/2 
    新添 scroll-view item的居中滑动
    配置
        ##必要配置
         // scroll-view 元素 class 或 id
        v_scrollClass:""
         //  scroll-view  子元素 class
        v_scrollItemClass:""
        可选配置
            //自定义scroll-left 存储变量
        v_scrollLeftModel

*/
const mixin_scrollToView = require("./mixin_scrollToView");
export default {
    data() {
        return {
            /* ----------------  常用配置项 start  ---------------- */

            // tabs数据列表
            v_tabsInfo: [{
                //标题
                title: "全部"
                // query type
                , type: 0
                // 页码
                , pageCount: 1
                // 数据是否加载完
                , end: false
                // 数据列表
                , list: []
                /* 
                // 置顶数据
                , topList: []
                // 置顶数据合并 key
                , topKey: "" 
                */
            }]
            // tabs索引
            , v_tabsIndex: 0
            // tabs http path
            , v_tabsHttpPath: ""
            // 列表初次加载生命周期事件 - onLoad onShow custom自定义
            , v_tabsInitLife: "custom"
            // tabs http query转换设置
            , v_tabsHttpKeys: {
                type: "type"
                , pageCount: "page"
                , v_tabsPageLimit: "limit"
            }
            // 是否使用 vant tabs
            , v_setVantAuto: false
            // 是否开启  下拉刷新
            , v_openPullDownRefresh: false
            // 是否开启  触底加载
            , v_openReachBottom: false
            // 是否开启滑动切换
            , v_openScrollToView: false
            /* ---------------- 常用配置项 end  ---------------- */
            //scroll-view 元素 class 或 id
            , v_scrollClass: ""
            // scroll-view  子元素 class
            , v_scrollItemClass: ""
            // scroll-view scroll-left载入的model
            , v_scrollLeftModel: "v_scrollLeft"
            // scroll-vew data  scrollleft -- model
            , v_scrollLeft: ""
            // tabs一页数据量
            , v_tabsPageLimit: 10
            // tabs query - limit
            , v_tabsPageLimitKeyName: "limit"
            // 切换tabs是否自动刷新
            , v_tabsRefreshAuto: true
            // tabs 是否处于触底加载事件中
            , v_tabsReachBottomLoading: false
            // tabs 当前页码加载完毕 提示
            , v_tabsEndNoticText: "已经到底了哦"
            // tabs 当前页码加载完毕 提示是否显示
            , v_tabsEndNoticShow: true
            // tabs 触底加载文本提示
            , v_tabsReachBottomLoadingText: "loading..."
            // 列表刷新延迟回调时间
            , v_tabsPullDownRefreshCallbackTime: 500
            // 列表刷新成功的提示
            , v_tabsPullDownRefreshNotic: {
                success: "列表刷新成功！"
                , fail: "列表刷新失败！"
            }
        }
    }
    , mixins: [mixin_scrollToView]
    /* ,computed:{
        // tabs http query 合并的参数
        v_tabsHttpQueryAssignInfo(){
            return {};
        }
    } */

    , onLoad() {
        this.v_getTabsInitLife("onLoad");
    }
    , onShow() {
        this.v_getTabsInitLife("onShow");
    }
    , onPullDownRefresh() {
        if (this.v_openPullDownRefresh) {
            this.v_tabsPullDownRefresh();
        }
    }
    , onReachBottom() {
        if (this.v_openReachBottom) {
            this.v_tabsReachBottom();
        }
    }
    , methods: {
        /* ----------------  必须配置项 start  ---------------- */
        /* 
            自定义处理当前列表参数  每个项目可根据接口单独设置
            list  列表
            end   列表是否加载结束
            传入的值 
                res 接口返回值
                tabsItem    v_tabsInfo[v_tabsIndex] 当前索引对象
                concatAuto  是否拼接  true 拼接 false 赋值
            返回一个新的 当前索引对象
            
        */
        v_updateTabsItem({
            res
            , tabsItem
            , concatAuto
        }) {
            const page = this;
            //前后台定义 一页数据量
            const { data } = res;
            const { v_tabsPageLimit } = page;
            tabsItem.end = data.length < v_tabsPageLimit;
            /* 
                //通过接口返回  总页数
                const { data: { total, list:data } } = res;
                const { pageCount } = tabsItem;
                tabsItem.end = total == 0 || pageCount == total;;
            
            */
            if (concatAuto) {
                tabsItem.list = tabsItem.list.concat(data);
            } else {
                tabsItem.list = data;
            }

            return tabsItem;
        }
        /* ----------------  必须配置项 end  ---------------- */

        /*
            // ## 对 tabsInfo data 进行处理
            ,v_tabsDataTransform( tabsData ){} 
        */
        // 置顶数据筛选
        , v_topMerge(navItem) {
            // 置顶数据拼接
            const { topList, topKey, list } = navItem;
            if (topList && topList.length) {
                if (topKey && list.length) {
                    const { list } = navItem;

                    for (let i = list.length - 1; i >= 0; i--) {
                        let listItem = list[i];
                        let hasTop = topList.some(item => {
                            return item[topKey] == listItem[topKey];
                        })

                        if (hasTop) {
                            list.splice(i, 1);
                        }
                    }
                }

                navItem.list.unshift(...topList);
            }
            return navItem;
        }
        // 初次加载
        , v_getTabsInitLife(lifeName) {
            const page = this;
            const { v_tabsRefreshAuto, v_tabsIndex, v_tabsInitLife } = page;

            if (v_tabsInitLife && v_tabsInitLife === lifeName) {
                page.v_tabsChange(undefined, {
                    tabs_index: v_tabsIndex,
                    refresh_auto: v_tabsRefreshAuto
                });
            }
        }
        //加载分页内容
        , v_getTabsPage(params) {
            const page = this;
            const { v_tabsHttpKeys
                , v_tabsHttpQueryAssignInfo
                , v_tabsHttpPath
            } = page;
            const httpQuerys = {};
            Object.keys(v_tabsHttpKeys)
                .forEach(key => {

                    const transKey = v_tabsHttpKeys[key];
                    httpQuerys[transKey] = params[key];
                });
            if (v_tabsHttpQueryAssignInfo) {
                Object.assign(httpQuerys, v_tabsHttpQueryAssignInfo);
            }
            // 搜索关键字
            const { searchKeys } = params;
            if (searchKeys) {
                Object.assign(httpQuerys, searchKeys);
            }
            return page.$get(v_tabsHttpPath, httpQuerys);
        }
        // 切换导航
        , v_tabsChange(event, navInfo) {
            const page = this;
            let { v_tabsInfo, v_tabsPageLimit, v_tabsRefreshAuto } = page;
            if (!v_tabsInfo.length) {
                throw Error("tabs Error: tabsInfo length is null");
            }
            let v_tabsIndex;
            let refreshAuto = v_tabsRefreshAuto;
            let success;
            let fail;
            // 搜索关键字  Object 类型 
            let searchKeys;
            if (event) {
                /* 判断是否为event 组件方法监听 还是自定义监听 */
                const eventType = typeof event;
                /* 如果是使用组件方法 目前 u-tabs van-tabs 皆只有索引 */
                if( eventType === Number || eventType === String ){
                    v_tabsIndex = event || 0;
                }else{
                    v_tabsIndex = event.currentTarget.dataset.tabs_index;
                    const eventDataset = event.currentTarget.dataset;
                    searchKeys = eventDataset.search_keys;
                    if ("refresh_auto" in eventDataset) {
                        refreshAuto = eventDataset.refresh_auto;
                    }
                }
            } else if (navInfo) {
                v_tabsIndex = navInfo.tabs_index;
                searchKeys = navInfo.search_keys;
                success = navInfo.success;
                fail = navInfo.fail;
                if ("refresh_auto" in navInfo) {
                    refreshAuto = navInfo.refresh_auto;
                }
            } else {
                throw ReferenceError("tabsChange missing required parameter")
            }

            /* 是否滑动切换 */
            const { v_openScrollToView, v_setVantAuto } = page;
            // 前提不使用 vant组件
            if (!v_setVantAuto && v_openScrollToView) {
                const { v_scrollClass, v_scrollItemClass, v_scrollLeftModel } = page;
                page.scrollIntoView({
                    scrollClass: v_scrollClass
                    , scrollItemClass: v_scrollItemClass
                    , scrollIndex: v_tabsIndex
                    , scrollLeftModel: v_scrollLeftModel
                });
            }

            let navItem = v_tabsInfo[v_tabsIndex];
            // return false;
            // 切换加载  条件
            // 强制刷新开启
            //  或者   没有加载完  并且  数据为0
            if (refreshAuto || (
                !navItem.end
                &&
                !navItem.list.length
            )) {
                if (refreshAuto) {
                    navItem.pageCount = 1;
                }
                const { type, pageCount } = navItem;

                page.v_getTabsPage({
                    type
                    , pageCount
                    , v_tabsPageLimit
                    , searchKeys
                })
                    .then(res => {
                        const { v_tabsDataTransform } = page;
                        if (v_tabsDataTransform && typeof v_tabsDataTransform === "function") {
                            list = v_tabsDataTransform(list);
                        }
                        // 处理当前列表数据  是否结束   列表数据赋值
                        navItem = page.v_updateTabsItem({ tabsItem: navItem, res, concatAuto: false });
                        // 处理当前列表  置顶数据   
                        navItem = page.v_topMerge(navItem);

                        if (success && typeof success === "function") {
                            success();
                        }

                    }).catch(err => {
                        if (fail && typeof fail === "function") {
                            fail(err);
                        } else {
                            page.$fail(err);
                        }
                    });
            }



        }
        // tabs 下拉刷新
        , v_tabsPullDownRefresh(noticAuto = true) {
            const page = this;
            const { v_tabsIndex, v_tabsPullDownRefreshCallbackTime } = page;
            page.v_tabsChange(undefined, {
                tabs_index: v_tabsIndex
                , refresh_auto: true
                , success() {
                    setTimeout(function () {
                        wx.stopPullDownRefresh();
                        if (noticAuto) {
                            const { v_tabsPullDownRefreshNotic } = page;
                            page.$log(v_tabsPullDownRefreshNotic.success);
                        }
                    }, v_tabsPullDownRefreshCallbackTime);
                }
                , fail(err) {
                    setTimeout(function () {
                        wx.stopPullDownRefresh();
                        if (noticAuto) {
                            const { v_tabsPullDownRefreshNotic } = page;
                            page.$fail(v_tabsPullDownRefreshNotic.fail || err);
                        }
                    }, v_tabsPullDownRefreshCallbackTime);
                }
            });
        }
        // tabs 触底加载
        , v_tabsReachBottom() {
            const page = this;
            let { v_tabsInfo, v_tabsIndex, v_tabsPageLimit, v_tabsReachBottomLoading } = page;
            if (!v_tabsInfo.length) {
                throw Error("tabs Error: tabsInfo length is null");
            }
            let navItem = v_tabsInfo[v_tabsIndex];
            const { pageCount, end, type } = navItem;
            // 如果处于触底加载事件中  退出
            if (v_tabsReachBottomLoading) {
                return false;
            }
            if (end) {
                return false;
            } else {
                page.v_tabsReachBottomLoading = true;
                const nextpageCount = pageCount + 1;
                page.v_getTabsPage({
                    type
                    , pageCount: nextpageCount
                    , v_tabsPageLimit
                }).then(res => {
                    // 处理当前列表数据  是否结束   列表数据赋值
                    navItem = page.v_updateTabsItem({ tabsItem: navItem, res, concatAuto: true });
                    navItem.pageCount = nextpageCount;
                    page.v_tabsReachBottomLoading = false;
                    // navItem = page.v_topMerge( navItem );
                }).catch(err => {
                    page.v_tabsReachBottomLoading = false;
                    page.$fail(err);
                });
            }
        }
    }

}